package index.btree;

import compiler.absyn.Constant;

import storage.file.Block;
import storage.record.TableInfo;
import storage.tx.Transaction;

public class BTreeDir {
	private TableInfo md;
	private Transaction tx;
	private String filename;
	private BTreePage contents;
	
	BTreeDir(Block blk, TableInfo md, Transaction tx){
		this.md = md;
		this.tx = tx;
		filename = blk.getFileName();
		contents = new BTreePage(blk, md, tx);
	}
	
	public void close(){
		contents.close();
	}
	
	public int search(Constant searchkey){
		Block childblk = findChildBlock(searchkey);
		while(contents.getFlag()>0){
			contents.close();
			contents = new BTreePage(childblk, md, tx);
			childblk = findChildBlock(searchkey);
			System.out.println("childblk");
		}
		return childblk.getBlkNum();
	}
	
	public void makeNewRoot(DirEntry e){
		Constant firstval = contents.getDataVal(0);
		int level = contents.getFlag();
		Block newblk = contents.appendNew(filename, level);
		contents.moveTo(newblk);
		DirEntry oldroot = new DirEntry(firstval, newblk.getBlkNum());
		insertEntry(oldroot);
		insertEntry(e);
		contents.setFlag(level + 1);
	}

	public DirEntry insert(DirEntry e){
		if (contents.getFlag() == 0){
			return insertEntry(e);
		}
		Block childblk = findChildBlock(e.dataval());
		BTreeDir child = new BTreeDir(childblk, md, tx);
		DirEntry myentry = child.insert(e);
		child.close();
		return (myentry != null)?insertEntry(myentry):null;
	}
	
	private DirEntry insertEntry(DirEntry e){
		int newslot = 1 + contents.findSlotBefore(e.dataval());
		contents.insertDir(newslot, e.dataval(), e.blockNum());
		if(!contents.isFull())
			return null;
		int level = contents.getFlag();
		Block newblk = contents.appendNew(filename, level);
		BTreePage newpage = new BTreePage(newblk, md, tx);
		Constant splitval = contents.split(newpage);
		newpage.close();
		return new DirEntry(splitval, newblk.getBlkNum());
	}
	
	private Block findChildBlock(Constant searchkey){
		int slot = contents.findSlotBefore(searchkey);
		if (contents.getDataVal(slot + 1).equals(searchkey))
			slot++;
		int blknum = contents.getChildNum(slot);
		return new Block(filename, blknum);
	}
}